home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / OrdColl.C < prev    next >
C/C++ Source or Header  |  1990-12-04  |  6KB  |  348 lines

  1. //$OrdCollection,OrdCollectionIter,RevOrdCollectionIter$
  2. #include "OrdColl.h"
  3. #include "Error.h"
  4. #include "FixedStorage.h"
  5.  
  6. const int cOrdColShrinkFactor = 2,
  7.       cMinExpand = 8;
  8.  
  9. //---- ordered collection ------------------------------------------------------
  10.  
  11. MetaImpl(OrdCollection, (TP(cont), 0));
  12.  
  13. static void ObjNotFound(char *where, Object *which)
  14. {
  15.     Error(where, "object (0x%x) not found", (int) which);
  16. }
  17.  
  18. OrdCollection::OrdCollection(int s)
  19. {
  20.     cont= new ObjArray(s);
  21.     size= 0;
  22.  
  23. OrdCollection::~OrdCollection()
  24. {
  25.     SafeDelete(cont);
  26. }
  27.  
  28. void OrdCollection::InitNew()
  29. {
  30.     cont= new ObjArray(cCollectionInitCap);
  31.     size= 0;
  32. }
  33.  
  34. void OrdCollection::FreeAll()
  35. {
  36.     for (int i= 0; i < size; i++) {
  37.     Object *op= cont->At(i);
  38.     if (op) {
  39.         op->FreeAll();
  40.         SafeDelete(op);
  41.     }
  42.     }
  43.     size= 0;
  44. }
  45.  
  46. ObjPtr OrdCollection::At(int index)
  47. {
  48.     if (index < 0 || index >= size)
  49.     Error ("At", "illegal index %d (size= %d)", index, size);
  50.     if (!AnyDeleted())
  51.     return cont->UncheckedAt(index);
  52.  
  53.     // take care of deleted objects
  54.     return SeqCollection::At(index);
  55. }
  56.  
  57. ObjPtr OrdCollection::After(ObjPtr op)
  58. {
  59.     if (op == 0) 
  60.     return 0;
  61.     int i= cont->IndexOf(op);
  62.     if (i == -1) { 
  63.     ObjNotFound("After", op);
  64.     return 0;
  65.     }
  66.     if (i == size-1)
  67.     return 0;    
  68.     return cont->At(i+1);
  69. }
  70.  
  71. ObjPtr OrdCollection::Before(ObjPtr op)
  72. {
  73.     if (op == 0) 
  74.     return 0;
  75.     int i= cont->IndexOf (op);
  76.     if (i == -1) { 
  77.     ObjNotFound("Before", op);
  78.     return 0;
  79.     }
  80.     if (i == 0)
  81.     return 0;    
  82.     return cont->At(i-1);
  83. }
  84.  
  85. ObjPtr OrdCollection::First()
  86. {
  87.     return At(0);
  88. }
  89.  
  90. ObjPtr OrdCollection::Last()
  91. {
  92.     int i;
  93.     Object *op;
  94.  
  95.     for (i= Size()-1; i >= 0; i--) {
  96.     op= cont->At(i);
  97.     if (!op->IsDeleted())
  98.         return op;
  99.     }
  100.     return 0;
  101. }
  102.  
  103. int OrdCollection::Capacity()
  104. {
  105.     return cont->Size();
  106. }
  107.  
  108. ObjPtr OrdCollection::Add(ObjPtr op)
  109. {
  110.     if (CheckNotNull("Add", op))
  111.     return 0;
  112.     AddAt(size, op);
  113.     return 0;
  114. }
  115.  
  116. void OrdCollection::InsertAtPos(ObjPtr at, ObjPtr op, bool byPtr, bool after, char *name) 
  117. {
  118.     if (CheckNotNull(name, op))
  119.     return;
  120.     if (cont->Size() <= 0)
  121.     return;
  122.     CheckActiveIter(name);
  123.     int i;
  124.     if (byPtr)
  125.     i= cont->IndexOfPtr(at);
  126.     else
  127.     i= cont->IndexOf(at);
  128.     if (i == -1) 
  129.     ObjNotFound(name, op);
  130.     if (after)
  131.     i++;
  132.     AddAt(i, op);
  133. }
  134.  
  135. void OrdCollection::InsertAfter(ObjPtr after, ObjPtr op)
  136. {
  137.     InsertAtPos(after, op, FALSE, TRUE, "InsertAfter");
  138. }
  139.  
  140. void OrdCollection::InsertAfterPtr(ObjPtr after, ObjPtr op)
  141. {
  142.     InsertAtPos(after, op, TRUE, TRUE, "InsertAfterPtr");
  143. }
  144.  
  145. void OrdCollection::InsertBefore(ObjPtr before, ObjPtr op)
  146. {
  147.     InsertAtPos(before, op, FALSE, FALSE, "InsertBefore");
  148. }
  149.  
  150. void OrdCollection::InsertBeforePtr(ObjPtr before, ObjPtr op)
  151. {
  152.     InsertAtPos(before, op, TRUE, FALSE, "InsertBeforePtr");
  153. }
  154.  
  155. ObjPtr OrdCollection::Remove(ObjPtr e)
  156. {
  157.     register ObjPtr t= 0;
  158.  
  159.     if (e == 0) 
  160.     return 0;
  161.     for (int i= 0; i < size; i++) {
  162.     Object* tmp; // g++ ??
  163.     tmp= cont->At(i);
  164.     if (e->IsEqual(tmp))
  165.         t= DoRemoveAt(i);
  166.     }
  167.     return t;
  168. }
  169.  
  170. ObjPtr OrdCollection::RemovePtr(ObjPtr e)
  171. {
  172.     register ObjPtr t= 0;
  173.  
  174.     if (e == 0) 
  175.     return 0;
  176.     for (int i = 0; i < size; i++)
  177.     if (e == cont->At(i))
  178.         t= DoRemoveAt(i);
  179.     return t;
  180. }
  181.  
  182. void OrdCollection::AddAt(int at, ObjPtr op)
  183. {
  184.     register int j;
  185.  
  186.     if (CheckNotNull("AddAt", op))
  187.     return;
  188.     CheckActiveIter("AddAt");
  189.     if (at > size)
  190.     Error("AddAt", "out of range");
  191.     if (size == cont->Size())
  192.     cont->Expand (GrowBy(max(cont->Size(), cMinExpand)));
  193.     for (j= size-1; j >= at; j--)
  194.     (*cont)[j+1]= (*cont)[j];
  195.  
  196.     (*cont)[at]= op;
  197.     size++;
  198.     Changed();
  199. }
  200.  
  201. ObjPtr OrdCollection::RemoveAt(int i)
  202. {
  203.     if (!AnyDeleted())
  204.     return DoRemoveAt(i);
  205.     return RemovePtr(At(i));
  206. }
  207.  
  208. ObjPtr OrdCollection::DoRemoveAt(int i)
  209. {
  210.     ObjPtr t;
  211.     register int j;
  212.  
  213.     t= cont->RemoveAt(i);
  214.     if (InIterator()) {
  215.     cont->AtPut (i, new DeletedObject);
  216.     AnnounceRemove();
  217.     Changed();
  218.     return t;
  219.     }
  220.     for (j= i; j < size-1; j++)
  221.     cont->AtPut(j, cont->At(j+1));
  222.     cont->AtPut(size-1, 0);
  223.     
  224.     size--;
  225.     if (LowWaterMark()) 
  226.     cont->Expand (cont->Size() / cOrdColShrinkFactor);
  227.     
  228.     Changed();
  229.     return t;
  230. }
  231.  
  232. void OrdCollection::RemoveDeleted()
  233. {
  234.     Object *op;
  235.     for (int j= 0; j < size;) {
  236.     op= cont->At(j);
  237.     if (op && op->IsDeleted()) {
  238.         DoRemoveAt(j);
  239.         SafeDelete(op);
  240.     }
  241.     else 
  242.         j++;
  243.     }
  244. }
  245.  
  246. void OrdCollection::Empty (int s)                                         
  247. {
  248.     CheckActiveIter("Empty");
  249.     SafeDelete(cont);
  250.     cont= new ObjArray(max(s,4)); 
  251.     size= 0; 
  252. }
  253.  
  254. Iterator *OrdCollection::MakeIterator() 
  255.     return new OrdCollectionIter(this); 
  256. }
  257.  
  258. Iterator *OrdCollection::MakeReversedIterator () 
  259.     return new RevOrdCollectionIter(this); 
  260. }
  261.  
  262. void OrdCollection::Sort()
  263. {
  264.     CheckActiveIter("Sort");
  265.     cont->Sort(size);
  266. }
  267.  
  268. int OrdCollection::BinarySearch(ObjPtr op)
  269. {
  270.     return cont->BinarySearch(op, size);
  271. }
  272.  
  273. //---- ordered collection iterator ---------------------------------------------
  274.  
  275. OrdCollectionIter::OrdCollectionIter(Collection *s)
  276.     cs= (OrdCollection *)s;
  277.     ce= 0; 
  278. }
  279.  
  280. OrdCollectionIter::~OrdCollectionIter()
  281. {
  282.     IteratorEnd();
  283. }
  284.  
  285. void OrdCollectionIter::Reset(Collection *s)
  286. {
  287.     if (s == 0)
  288.     s= Coll();
  289.     cs= (OrdCollection *)s;
  290.     ce= 0;
  291.     Iterator::Reset(s);
  292. }
  293.  
  294. Collection *OrdCollectionIter::Coll()
  295. {
  296.     return cs;
  297. }
  298.  
  299. ObjPtr OrdCollectionIter::operator()()
  300. {
  301.     IteratorStart();
  302.     // find next non deleted object
  303.     for ( ;ce < cs->Size() && cs->cont->UncheckedAt(ce)->IsDeleted(); ce++)
  304.     ;
  305.     if (ce < cs->Size()) 
  306.     return cs->cont->UncheckedAt(ce++);
  307.     IteratorEnd();
  308.     return 0;
  309. }
  310.  
  311. void *OrdCollectionIter::operator new(size_t sz)
  312. {
  313.     return MemPools::Alloc(sz);
  314. }
  315.  
  316. void OrdCollectionIter::operator delete(void *vp)
  317. {
  318.     MemPools::Free(vp, sizeof(OrdCollectionIter)); 
  319. }
  320.  
  321. //---- RevOrdCollectionIter ----------------------------------------------------
  322.  
  323. RevOrdCollectionIter::RevOrdCollectionIter(Collection *s) : OrdCollectionIter(s)
  324. {
  325.     ce= cs->Size()-1;
  326. }
  327.  
  328. void RevOrdCollectionIter::Reset(Collection *s)
  329. {
  330.     OrdCollectionIter::Reset(s);
  331.     ce= cs->Size()-1;
  332. }
  333.  
  334. ObjPtr RevOrdCollectionIter::operator()()
  335. {
  336.     IteratorStart();
  337.     // find next non deleted object
  338.     for (; ce >= 0 && cs->cont->At(ce)->IsDeleted(); ce--);
  339.     if (ce >= 0) 
  340.     return cs->cont->UncheckedAt(ce--);
  341.     IteratorEnd();
  342.     return 0;
  343. }
  344.